package top.guxx.mall.config;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Author：Guxx
 * @Description：
 * @Date：2024/11/2 21:06
 * @Filename：RedisService
 */
@Component
public class RedisService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    // 设置字符串值
    public void set(String key, String value, Long timeout) {
        stringRedisTemplate.opsForValue().set(key, value, timeout);
    }

    public void setWithExpire(String key, String value, Long expire) {
        stringRedisTemplate.opsForValue().set(key, value, expire);
    }

    // 获取字符串值
    public String get(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }

    // 设置字符串值并设置过期时间（单位：秒）
    public void setWithExpire(String key, String value, long timeout) {
        stringRedisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
    }

    // 判断键是否存在
    public boolean hasKey(String key) {
        return stringRedisTemplate.hasKey(key);
    }

    // 删除键
    public void delete(String key) {
        stringRedisTemplate.delete(key);
    }

    public void putAllWithExpire(String key, Map<String, String> map, Integer expire){
        stringRedisTemplate.opsForHash().putAll(key, map);
        stringRedisTemplate.expire(key, expire, TimeUnit.SECONDS);
    }

    public Map<Object, Object> getMap(String key){
        return stringRedisTemplate.opsForHash().entries(key);
    }

    /**
     * 向Redis List中添加元素（左插入）
     *
     * @param key   Redis键
     * @param value 要插入的值
     * @return 插入后列表的长度
     */
    public Long leftPush(String key, String value) {
        return stringRedisTemplate.opsForList().leftPush(key, value);
    }

    /**
     * 向Redis List中添加元素（右插入）
     *
     * @param key   Redis键
     * @param value 要插入的值
     * @return 插入后列表的长度
     */
    public Long rightPush(String key, String value) {
        return stringRedisTemplate.opsForList().rightPush(key, value);
    }

    /**
     * 从Redis List中获取元素（左弹出）
     *
     * @param key Redis键
     * @return 弹出的值
     */
    public String leftPop(String key) {
        return stringRedisTemplate.opsForList().leftPop(key);
    }

    /**
     * 从Redis List中获取元素（右弹出）
     *
     * @param key Redis键
     * @return 弹出的值
     */
    public String rightPop(String key) {
        return stringRedisTemplate.opsForList().rightPop(key);
    }

    /**
     * 获取Redis List中的所有元素
     *
     * @param key Redis键
     * @return 列表中的所有元素
     */
    public List<String> range(String key, long start, long end) {
        return stringRedisTemplate.opsForList().range(key, start, end);
    }

    /**
     * 获取Redis List的长度
     *
     * @param key Redis键
     * @return 列表的长度
     */
    public Long size(String key) {
        return stringRedisTemplate.opsForList().size(key);
    }

    /**
     * 删除Redis List中的元素
     *
     * @param key   Redis键
     * @param count 要删除的元素数量
     * @param value 要删除的元素值
     * @return 删除的元素数量
     */
    public Long remove(String key, long count, String value) {
        return stringRedisTemplate.opsForList().remove(key, count, value);
    }

    /**
     * 设置Redis List的过期时间
     *
     * @param key Redis键
     * @param timeout 过期时间
     * @param unit 时间单位
     */
    public void expire(String key, long timeout, TimeUnit unit) {
        stringRedisTemplate.expire(key, timeout, unit);
    }

    /**
     * 获取Redis List中的所有元素
     *
     * @param key Redis键
     * @return 列表中的所有元素
     */
    public List<String> getAllElements(String key) {
        return stringRedisTemplate.opsForList().range(key, 0, -1);
    }

    public Long decr(String key, Long delta){
        return stringRedisTemplate.opsForValue().decrement(key, delta);
    }
    public Long incr(String key, Long delta){
        return stringRedisTemplate.opsForValue().increment(key, delta);
    }

    private static final String DELAYED_QUEUE_KEY = "delayedQueue";

    /**
     * 添加任务到延迟队列
     * @param massage 任务ID
     * @param delayInSeconds 延迟时间（秒）
     */
    public void addTaskToQueue(String massage, long delayInSeconds) {
        long executeTime = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(delayInSeconds);
        stringRedisTemplate.opsForZSet().add(DELAYED_QUEUE_KEY, massage, executeTime);
    }

}
